import { Button, Modal, Spin, Tabs, message } from 'antd';
import React, { useEffect, useState } from 'react';
import type { BackDataProps } from '../services';
import { wxTagsList } from '../services';
import ResultTags from './ResultTags';
import TextTagsForm from './TextTagsForm';

export interface Props {
  value?: BackDataProps;
  defaultValue?: BackDataProps;
  onChange?: (values: BackDataProps) => void;
  require?: boolean;
  placeholder?: string; // 输入提示
  maxLength?: string; // 文字标签总字数
  minTagCount?: number | undefined; // 标签最少个数
  maxTagCount?: number | undefined; // 标签最大个数
  columns?: (API.FormListType & {
    fieldProps: { maxLength?: number; minLength?: number };
  })[];
}

export interface DataProps {
  self_tags?: string[];
}

export interface ResultDataProps {
  type?: number | string;
  value?: any[];
  categoryName?: string;
}

const { TabPane } = Tabs;
/**
 * 标签选择组件
 */
const CreateTags: React.FC<Props> = (props) => {
  const {
    onChange,
    defaultValue,
    value = {
      LABEL_TYPE_COMMON: [],
      LABEL_TYPE_CUSTOMIZETEXT: [],
      LABEL_TYPE_ICON: [],
    },
    require = true,
    minTagCount = 1,
    maxTagCount = 3,
    maxLength = 16,
    columns,
  } = props;
  const [loading, setLoading] = useState<boolean>(false);
  const [confirmLoading, setConfirmLoading] = useState<boolean>(false);
  const [textType, setTextType] = useState<number>(1);
  const [option, setOption] = useState<any[]>([]);
  const [data, setData] = useState<DataProps>(); // data的数据格式为表单格式，key&value对象
  const [totalData, setTotalData] = useState<ResultDataProps[]>([]); // 渲染/提交数据用的数组
  const [resultList, setResultList] = useState<string[]>([]); // 最下方已选择的数据展示
  const [showList, setShowList] = useState<string[]>([]); // 标签表单项已选择的数据展示
  const [visible, setVisible] = useState<boolean>(false);
  const [tagMaxLength, setTagMaxLength] = useState<number>();
  const [tagMinLength, setTagMinLength] = useState<number>();

  // 获得两个数组的相同元素，返回数组
  const getSame = (arrFirst: string[], arrSecond: string[]) => {
    const newArr: string[] = [];
    (arrSecond || []).forEach((itemSecond: string) => {
      (arrFirst || []).forEach((itemFirst: string) => {
        if (itemSecond === itemFirst) newArr.push(itemFirst);
      });
    });
    return newArr;
  };

  // 初使化获取腾讯返回的标签数据
  const getOptions = () => {
    setLoading(true);
    if (!wxTagsList) return;
    (async () => {
      const { result } = await wxTagsList({});
      if (result) {
        setOption(result);
        if (defaultValue || value) {
          const initDataValue = defaultValue || value;
          // 初始化数据格式
          const initValue: any = {};
          result.forEach((item: any) => {
            // 目前只有文字标签
            if (item.name === '文字标签') {
              // 如果是文字标签，则存储文字标签的type
              setTextType(item.type);
              item.list?.forEach((itemListValue: any, index: number) => {
                initValue[`label_category_${item.type}_${index}`] = getSame(
                  itemListValue.list,
                  initDataValue.LABEL_TYPE_COMMON,
                );
              });
              initValue.self_tags = initDataValue.LABEL_TYPE_CUSTOMIZETEXT;
              setData(initValue);
              setShowList([
                ...initDataValue.LABEL_TYPE_COMMON,
                ...initDataValue.LABEL_TYPE_CUSTOMIZETEXT,
              ]);
              const min =
                columns && columns.length && columns[0].required ? 2 : 1;
              setTagMaxLength(
                columns && columns.length
                  ? columns[0].fieldProps?.maxLength
                  : 15,
              );
              setTagMinLength(
                columns && columns.length
                  ? columns[0].fieldProps?.minLength
                  : min,
              );
            }
          });
        }
      }
      setLoading(false);
    })();
  };

  // 标签表单值改变
  const handleFormChange = (changedValues: any, values: any) => {
    const newData = { ...data, ...values };
    setData(newData);
  };

  // 自定义文字标签-回车添加
  const handlePressEnter = (inputValue: string) => {
    if (inputValue) {
      const newData = {
        ...data,
        self_tags:
          data && data.self_tags
            ? [...data.self_tags, inputValue]
            : [inputValue],
      };
      setData(newData);
    }
  };

  // 删除标签
  const deleteTag = (type: string | number, label: string, isEdit?: string) => {
    // 文字标签 data的数据处理
    if (type === textType) {
      const deleteList: ResultDataProps[] = totalData.filter(
        (item: ResultDataProps) => item.value?.includes(label),
      );
      if (deleteList && deleteList.length) {
        const dataObj: DataProps = { ...data };
        const deleteObj = deleteList[0];
        dataObj[`${deleteObj.categoryName}`] = dataObj[
          `${deleteObj.categoryName}`
        ].filter((item: string) => item !== label);
        setData(dataObj);
        if (onChange && isEdit === 'edit') {
          const typeList = Object.keys(dataObj);
          const backData: BackDataProps = {
            LABEL_TYPE_COMMON: [],
            LABEL_TYPE_CUSTOMIZETEXT: [],
            LABEL_TYPE_ICON: [],
          };
          typeList.forEach((itemKeys: string) => {
            if (itemKeys !== 'self_tags') {
              backData.LABEL_TYPE_COMMON.push(...(dataObj[itemKeys] || []));
            } else {
              backData.LABEL_TYPE_CUSTOMIZETEXT.push(
                ...(dataObj[itemKeys] || []),
              );
            }
          });
          const keysList = Object.keys(backData);
          const resultStringList: string[] = [];
          keysList.forEach((item: string) => {
            resultStringList.push(...(backData[item] || []));
          });
          setShowList(resultStringList);
          onChange(backData);
        }
      }
    }
  };

  // 确定按钮
  const handleOk = () => {
    setConfirmLoading(true);
    let textLength = 0;
    resultList?.forEach((item: any) => {
      textLength += item.length;
    });
    // 必填校验
    if (require && textLength < (minTagCount || 1)) {
      setConfirmLoading(false);
      message.error('请选择标签');
      return;
    }
    // 最大个数校验
    if (resultList.length > maxTagCount) {
      setConfirmLoading(false);
      message.error(
        `最多可选 ${maxTagCount} 个标签，且标签总字数之和不超过 ${maxLength} 个字`,
      );
      return;
    }
    // 字数校验
    if (textLength > maxLength) {
      setConfirmLoading(false);
      message.error(
        `最多可选 ${maxTagCount} 个标签，且标签总字数之和不超过 ${maxLength} 个字`,
      );
      return;
    }
    // 处理前端数据为给后端的数据格式
    if (data) {
      const typeList = Object.keys(data);
      const resultStringList: string[] = [];
      typeList.forEach((item: string) => {
        resultStringList.push(...(data[item] || []));
      });
      // 弹窗下方已选择数据
      setResultList(resultStringList);
      // 给后端的数据
      const backData: BackDataProps = {
        LABEL_TYPE_COMMON: [],
        LABEL_TYPE_CUSTOMIZETEXT: [],
        LABEL_TYPE_ICON: [],
      };
      typeList.forEach((itemKeys: string) => {
        if (itemKeys !== 'self_tags') {
          backData.LABEL_TYPE_COMMON.push(...(data[itemKeys] || []));
        } else {
          backData.LABEL_TYPE_CUSTOMIZETEXT.push(...(data[itemKeys] || []));
        }
      });
      if (onChange) onChange(backData);
      setShowList(resultList);
      setConfirmLoading(false);
      setVisible(false);
    }
  };

  const handleCancel = () => {
    setVisible(false);
  };

  useEffect(() => {
    if (data) {
      // 根据data转化totalData与resultList(弹窗下方已选择文字标签)
      const keysList = Object.keys(data);
      const totalDataTransform: ResultDataProps[] = keysList.map(
        (itemKeys: string) => {
          if (itemKeys !== 'self_tags') {
            return {
              type: textType,
              value: data[itemKeys],
              categoryName: itemKeys,
            };
          }
          return {
            type: textType,
            value: data[itemKeys],
            categoryName: 'self_tags',
          };
        },
      );
      setTotalData(totalDataTransform);
      const resultStringList: string[] = [];
      keysList.forEach((item: string) => {
        resultStringList.push(...(data[item] || []));
      });
      setResultList(resultStringList);
    }
  }, [data, textType]);

  useEffect(() => {
    if (visible) {
      getOptions();
      setVisible(true);
    }
  }, [visible, getOptions]);

  useEffect(() => {
    getOptions();
  }, [getOptions]);

  return (
    <>
      {/* 因为目前只有文字标签，所以只展示已选的文字标签 */}
      {showList && showList.length ? (
        <ResultTags
          list={showList}
          type={textType || 1}
          onDelete={(type: number | string, element: string) => {
            deleteTag(type || textType, element, 'edit');
          }}
          onEdit={() => {
            setVisible(true);
          }}
        />
      ) : (
        <Button onClick={() => setVisible(true)}>+ 选择标签</Button>
      )}
      <Modal
        width={840}
        centered
        title="选择标签"
        visible={visible}
        destroyOnClose
        footer={
          <div
            style={{
              display: 'flex',
              justifyContent: 'flex-end',
              alignItems: 'center',
            }}
          >
            <span>
              <Button type="default" onClick={handleCancel}>
                取消
              </Button>
              <Button
                onClick={handleOk}
                type="primary"
                loading={confirmLoading}
              >
                确定
              </Button>
            </span>
          </div>
        }
        onCancel={handleCancel}
        bodyStyle={{ height: '700px', overflowY: 'hidden' }}
      >
        <Spin spinning={loading}>
          <Tabs type="card">
            {option &&
              option.length &&
              option.map((item: any) => {
                return (
                  <TabPane tab={item.name} key={item.type}>
                    {item.type === textType && (
                      <TextTagsForm
                        list={item.list}
                        onDelete={deleteTag}
                        type={item.type}
                        resultList={resultList}
                        totalData={totalData}
                        title={item.name}
                        maxTagCount={maxTagCount}
                        onValuesChange={handleFormChange}
                        data={data}
                        handlePressEnter={handlePressEnter}
                        min={
                          tagMinLength ||
                          (columns && columns.length && columns[0].required
                            ? 2
                            : 1)
                        }
                        max={tagMaxLength || 15}
                        require={require}
                      />
                    )}
                  </TabPane>
                );
              })}
          </Tabs>
        </Spin>
      </Modal>
    </>
  );
};

export default CreateTags;
